package com.kjlink.internal.workreport.plan.controller;

import cn.xuqiudong.common.base.model.BaseResponse;
import cn.xuqiudong.common.base.model.PageInfo;
import cn.xuqiudong.common.base.vo.Select2VO;
import com.kjlink.internal.workreport.base.controller.BaseController;
import com.kjlink.internal.workreport.base.enums.PlanStatusEnum;
import com.kjlink.internal.workreport.base.enums.PlanSubmissionStatusEnum;
import com.kjlink.internal.workreport.base.enums.UserType;
import com.kjlink.internal.workreport.helper.SessionHelper;
import com.kjlink.internal.workreport.plan.lookup.ToAddLookup;
import com.kjlink.internal.workreport.plan.model.WorkPlan;
import com.kjlink.internal.workreport.plan.model.WorkPlanDetail;
import com.kjlink.internal.workreport.plan.service.WorkPlanDetailService;
import com.kjlink.internal.workreport.plan.service.WorkPlanService;
import com.kjlink.internal.workreport.user.model.User;
import com.kjlink.internal.workreport.user.service.UserService;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;

/**
 * 功能: :周工作计划 控制层
 *
 * @author Vic.xu
 * @since 2024-10-10 09:56
 */
@RestController
@RequestMapping("/plan")
public class WorkPlanController extends BaseController<WorkPlanService, WorkPlan> {

    @Resource
    private UserService userService;

    @Resource
    private WorkPlanDetailService workPlanDetailService;

    /**
     * 绑定一些通用的下拉框参数
     *
     * @param model Model
     */
    @ModelAttribute
    private void bindSelect(Model model) {
        model.addAttribute("statusList", PlanStatusEnum.values());
        model.addAttribute("submissionStatusList", PlanSubmissionStatusEnum.values());
    }

    /**
     * 列表页
     */
    @RequestMapping(value = "/", method = {RequestMethod.GET, RequestMethod.POST})
    public ModelAndView index(WorkPlan lookup) {
        ModelAndView modelAndView = new ModelAndView("plan/list");
        PageInfo<WorkPlan> pager = service.page(lookup);
        pager.setLookup(lookup);
        modelAndView.addObject("pager", pager);

        return modelAndView;
    }

    /**
     * 前往打开新增周计划弹窗
     */
    @GetMapping("addDialog")
    public ModelAndView addDialog() {
        ModelAndView mv = new ModelAndView("plan/addDialog");
        mv.addObject("userList", findUserList());
        return mv;
    }

    /**
     * 前往编辑页面
     *
     * @param id id
     */
    @GetMapping("form/{id}")
    public ModelAndView form(@PathVariable Integer id) {
        ModelAndView mv = new ModelAndView("plan/form");
        mv.addObject("entity", service.findById(id));
        mv.addObject("details", workPlanDetailService.findByPlanId(id));
        return mv;
    }

    /**
     * 撤销提交
     */
    @GetMapping("revoke/{id}")
    public ModelAndView revoke(@PathVariable Integer id, RedirectAttributes attr) {
        updateStatus(id, PlanSubmissionStatusEnum.REVOKED);
        return redirectHome();
    }

    /**
     * 前往某个计划的详情
     */
    @GetMapping("detail/{id}")
    public ModelAndView detail(@PathVariable Integer id) {
        ModelAndView mv = new ModelAndView("plan/detail");
        mv.addObject("entity", service.findById(id));
        mv.addObject("details", workPlanDetailService.findByPlanId(id));
        return mv;
    }

    /**
     * 前往某个计划对应小组的当前周次的全部详情
     */
    @GetMapping("groupDetail/{id}")
    public ModelAndView groupDetail(@PathVariable Integer id, RedirectAttributes attrs) {
        ModelAndView mv = new ModelAndView("plan/group-detail");
        WorkPlan entity = service.findById(id);
        if (entity == null) {
            return redirectHome("不存在的周计划", attrs);
        }
        mv.addObject("entity", entity);
        mv.addObject("details", workPlanDetailService.findByGroupAndWeek(entity.getGroupId(), entity.getWeekNumber()));
        return mv;
    }


    /**
     * 前往新增或编辑页面：需要选择周次和用户信息等
     *
     * @param lookup 包含用户id和开始结束日期 是否带入上周未完成工作计划
     */
    @PostMapping("/toAdd")
    public ModelAndView toAdd(ToAddLookup lookup) {
        ModelAndView mv = new ModelAndView("plan/form");
        WorkPlan entity = service.findIfExist(lookup);
        //不存在表示为新增
        if (entity == null) {
            // 前往新增详情页面前先保存计划主表
            entity = service.saveBeforeAddDetail(lookup);
            //当为新增时候带入上周未完成的工作计划时
            WorkPlan lastWeek = service.findLastWeek(lookup);
            if (lastWeek != null) {
                List<WorkPlanDetail> workPlanDetails = workPlanDetailService.bringInLastWeek(lastWeek.getId());
                //把上周未完成的工作计划设置到当前周计划中： id置空
                for (WorkPlanDetail detail : workPlanDetails) {
                    detail.setPlanId(entity.getId());
                    detail.setId(null);
                }
                mv.addObject("details", workPlanDetails);
            }
        }
        mv.addObject("entity", entity);
        return mv;
    }

    /**
     * 批量异步json新增
     */
    @PostMapping("/batchInsert")
    public BaseResponse<?> batchInsert(Integer planId,
                                       @RequestParam(defaultValue = "false") boolean submit,
                                       @RequestBody List<WorkPlanDetail> list) {
        workPlanDetailService.batchSave(planId, list);
        //更新实际总工时
        BigDecimal actualEffort = list.stream().map(WorkPlanDetail::getActualEffort)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        WorkPlan workPlan = new WorkPlan();
        workPlan.setId(planId);
        workPlan.setActualEffort(actualEffort);
        if (submit) {
            workPlan.setSubmissionStatus(PlanSubmissionStatusEnum.SUBMITTED);
        }
        service.save(workPlan);
        return BaseResponse.success();
    }


    private List<Select2VO> findUserList() {
        User user = SessionHelper.currentUser();
        UserType type = user.getType();
        if (UserType.team == type || user.isAdmin()) {
            return userService.findByGroupId(user.getGroupId());
        }
        return Collections.singletonList(new Select2VO(user.getId(), user.getUserName()));
    }

    /**
     * 更新状态
     */
    private void updateStatus(Integer id, PlanSubmissionStatusEnum statusEnum) {
        WorkPlan workPlan = new WorkPlan();
        workPlan.setId(id);
        workPlan.setSubmissionStatus(statusEnum);
        service.save(workPlan);
    }

    @Override
    protected String home() {
        return "/plan/";
    }
}
